﻿using System;
using System.Collections;
using System.Net;

namespace LIK.NetworkTools
{
    internal class NetIpEnumeration : IEnumerable
    {
        private readonly string startAddress;
        private readonly string endAddress;

        internal static Int64 AddressToInt(IPAddress addr)
        {
            byte[] addressBits = addr.GetAddressBytes();

            Int64 retval = 0;
            for (int i = 0; i < addressBits.Length; i++)
            {
                retval = (retval << 8) + (int) addressBits[i];
            }

            return retval;
        }

        internal static Int64 AddressToInt(string addr)
        {
            return AddressToInt(IPAddress.Parse(addr));
        }

        internal static IPAddress IntToAddress(Int64 addr)
        {
            return IPAddress.Parse(addr.ToString());
        }

        public NetIpEnumeration(string startAddress, string endAddress)
        {
            this.startAddress = startAddress;
            this.endAddress = endAddress;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator) GetEnumerator();
        }

        public NetIpEnumerator GetEnumerator()
        {
            return new NetIpEnumerator(startAddress, endAddress);
        }
    }

    public class NetIpEnumerator : IEnumerator
    {
        private readonly string startAddress;
        private string endAddress;
        private Int64 currentIp;
        private readonly Int64 endIP;

        public NetIpEnumerator(string startAddress, string endAddress)
        {
            this.startAddress = startAddress;
            this.endAddress = endAddress;

            currentIp = NetIpEnumeration.AddressToInt(startAddress);
            endIP = NetIpEnumeration.AddressToInt(endAddress);
        }

        public bool MoveNext()
        {
            currentIp++;
            return (currentIp <= endIP);
        }

        public void Reset()
        {
            currentIp = NetIpEnumeration.AddressToInt(startAddress);
        }

        object IEnumerator.Current
        {
            get { return Current; }
        }

        public IPAddress Current
        {
            get
            {
                try
                {
                    return NetIpEnumeration.IntToAddress(currentIp);
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }


    }
}
